/**
 *******************************************************************************
 * @file hcli.h
 * @author .ISS_AUTO (hudandan@issauto.com)
 * @date 2025-04-01  1. Base Version.
 *
 * @brief Header file for the HCLI module.
 *        This module provides a command-line interface for interacting with
 *        embedded systems, including command registration, processing, and
 *        execution functionalities.
 *
 * @copyright Copyright (c) 2025 ISSAUTO TECH Co., Ltd. All rights reserved.
 *
 *******************************************************************************
 */

#ifndef __HCLI_H
#define __HCLI_H

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stringFunc.h" //!< o0_StrDelim

#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>


/* Private define ------------------------------------------------------------*/
/*!< 最大命令数 */
#define HCLI_CMD_MAX_NUM             (20)

/*!< 最大命令行参数个数 */
#define HCLI_CMD_ARG_MAX_NUM         (10)

/*!< 指令接收处理最大数 */
#define HCLI_PROCESS_READ_SIZE       (48U)

/*!< printf()输出最大字符数 */
#define HCLI_PRINTF_MAX_NUM          (256U)

/*!< 定时器(ms) */
#define HCLI_GET_TICK()                 STIMER_GET()
#define HCLI_IS_TIMEOUT(start, time)    STIMER_IS_TIMEOUT(start, time)

/*!< 参数分隔符处理 */
#define HCLI_ARGS_DELIM(line, p_argv, maxnum, delim)     o0_StrDelim(line, p_argv, maxnum, delim)


/*!< 故障码 */
#define HCLI_ERR_CMD_DEL_FAILED        (-3)  /*!< 指令删除失败，指令不存在 */
#define HCLI_ERR_CMD_ALREADY_ADDED     (-2)  /*!< 指令已存在，无法重复添加 */
#define HCLI_ERR_CMD_ADD_FAILED        (-1)  /*!< 指令添加失败 */
#define HCLI_ERR_NONE                  (0)   /*!< 无错误 */
#define HCLI_ERR_INVALID_CMD           (1)   /*!< 无效的指令 */
#define HCLI_ERR_EXECUTION_FAILED      (2)   /*!< 指令执行失败 */
#define HCLI_ERR_TIMEOUT               (3)   /*!< 指令执行超时 */


/*!< DEBUG */
#if !defined HCLI_ARGS_DELIM
    #error "HCLI_ARGS_DELIM is not defined. Please define it before including this header."
#endif

#define __HCLI_DEBUG      (0U)

/* Exported types ------------------------------------------------------------*/

/** @addtogroup
  * @{
  */
/*!< cli: <name> <cmd (include all args...)> */
#define ARGC_IDX_NAME         0
#define ARGC_IDX_CMD          1
#define ARGC_IDX_MAX_NUM      2

/*!< arg_max = 1: <u_line> */
#define ARGC_1_IDX_LINE       0

/*!< arg_max > 1: <u_cmd> <u_value0>... */
#define ARGC_N_IDX_CMD        0
#define ARGC_N_IDX_VALUE0     1
#define ARGC_N_IDX_VALUE1     2
// .
// .
// .

/**
 * @brief Command structure for HCLI.
 */
typedef struct {
    const char *name; /*!< Command name */
    const char *help; /*!< Help description for the command */
    unsigned char open; /*!< Command availability flag */
    unsigned char arg_max; /*!< Maximum number of arguments (excluding the command name) */
    void (*func)(unsigned int argc, char *argv[], void *userdata); /*!< Function pointer to the command handler */
} hcli_cmd_t;

/**
 * @brief Adapter structure for HCLI.
 */
typedef struct {
    unsigned int (*write)(const void *buf, unsigned int len); /*!< Function pointer for sending data */
    unsigned int (*read)(void *buf, unsigned int len); /*!< Function pointer for receiving data */
    void (*user_process)(void *obj, void *buf, unsigned int len); /*!< User-defined processing function */

    unsigned int (*read_passthrough)(const void *buf, unsigned int len); /*!< Function pointer for passthrough receiving */
    unsigned char echo; /*!< Echo enable flag */

    unsigned short cli_cmds_num; /*!< Number of CLI commands */
    const hcli_cmd_t *cli_cmds_list[HCLI_CMD_MAX_NUM]; /*!< List of CLI commands */

    unsigned int cli_timer; /*!< Timer for CLI command reception */
    unsigned short cli_cnt; /*!< Counter for CLI command reception */
    unsigned short cli_bufsize; /*!< Size of the CLI command reception buffer */
    unsigned char *cli_buf; /*!< Buffer for CLI command data */
} hcli_adapter_t;

/**
 * @brief HCLI object structure for managing the command-line interface.
 */
typedef struct hcli_obj {
    hcli_adapter_t adapt; /*!< Adapter for HCLI */
    void (*printf)(struct hcli_obj *p_hcli, const char *fmt, ...); /*!< Function pointer for formatted output */

    unsigned int process_timer;
    unsigned short cli_index; /*!< Index of the current CLI command */
} hcli_obj_t;

/**
  * @}
  */

/* Exported macro ------------------------------------------------------------*/
// #define hcli_log(M, ...)      USER_PRINTF("[HCLI:%4d] "M"\r\n", __LINE__, ##__VA_ARGS__)
#define hcli_log(M, ...)

#if (0)
#define HCLI_ASSERT(x)   if (!(x)) { \
        printf("ASSERT(%s) at file %s:%d\r\n", #x, __FILE__, __LINE__);\
        while (1); \
    }
#else
#define HCLI_ASSERT(x)    ((void)0)
#endif

/* Exported functions --------------------------------------------------------*/
extern int get_value_string(char *input, char **output);
extern int get_value_number(char *input, char **output);
extern int get_value_number_letter(char *input, char **output);

/* Exported functions --------------------------------------------------------*/
int hcli_cmds_add(hcli_obj_t *p_obj, hcli_cmd_t *cmd, unsigned int n);
int hcli_cmds_del(hcli_obj_t *p_obj, hcli_cmd_t *cmd, unsigned int n);

void hcli_recv_process(hcli_obj_t *p_obj, char *buf, unsigned int size);
void hcli_process(hcli_obj_t *p_obj, unsigned int period);
void hcli_init(hcli_obj_t *p_obj, const hcli_adapter_t *p_adapt);


#endif/* __HCLI_H */

/* END OF FILE ---------------------------------------------------------------*/
